package com.shr25.v2.controller;

import com.shr25.v2.common.base.BaseController;
import com.shr25.v2.common.domain.AjaxResult;
import com.shr25.v2.model.admin.TSysNotice;
import com.shr25.v2.model.admin.TSysUser;
import com.shr25.v2.model.custom.SysMenu;
import com.shr25.v2.qq.QQUserInfo;
import com.shr25.v2.shiro.util.ShiroUtils;
import com.shr25.v2.util.ServletUtils;
import com.shr25.v2.util.StringUtils;
import com.wf.captcha.utils.CaptchaUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;

/**
 * 后台方法
 *
 * @author fuce
 * @ClassName: HomeController
 * @date 2019-10-21 00:10
 */
@Slf4j
@Controller
@RequestMapping("/admin")
public class  AdminController extends BaseController {

    private static Logger logger = LoggerFactory.getLogger(AdminController.class);

    private String prefix = "admin";

    @ApiOperation(value = "获取用户支付账号", notes = "后台管理")
    @GetMapping({"/getCollectionAccount"})
    @ResponseBody
    public AjaxResult index(HttpServletRequest request, Long id) {
        TSysUser sysUser = sysUserService.selectTSysUserById(id);
        if(sysUser != null){
            return successData(sysUser.getCollectionAccount());
        }else{
            return error("未找到用户");
        }
    }

    @ApiOperation(value = "首页", notes = "后台管理")
    @GetMapping({"", "/index"})
    public ModelAndView index(HttpServletRequest request, ModelMap model) {
        request.getSession().setAttribute("user", sysUserService.selectTSysUserById(ShiroUtils.getUserId()));
        if(ShiroUtils.getSubjct().isPermitted("system:service:view")){
            request.getSession().setAttribute("isbuildLinkHtml", true);
        }else{
            request.getSession().setAttribute("isbuildLinkHtml", false);
        }
        // 获取公告信息
        List<TSysNotice> notices = sysNoticeService.getuserNoticeNotRead(ShiroUtils.getUser(), 0);
        request.getSession().setAttribute("notices", notices);
       return modelAndView(prefix + "/index");
    }

    @ApiOperation(value = "首页", notes = "内容")
    @GetMapping({"", "/home"})
    public ModelAndView home(HttpServletRequest request, ModelMap model) {
        request.getSession().setAttribute("user", sysUserService.selectTSysUserById(ShiroUtils.getUserId()));
        if(ShiroUtils.getSubjct().isPermitted("system:service:view")){
            return redirectView("/ServiceController/view");
        }{
            List<TSysNotice> sysNotices = sysNoticeService.getNEW();
            if (sysNotices == null || sysNotices.size() <= 0) {
                TSysNotice sysNotice = new TSysNotice();
                sysNotice.setId(0L);
                sysNotice.setTitle("暂无公告");
                sysNotice.setCreateTime(new Date());
                sysNotices.add(sysNotice);
            }
            model.addAttribute("sysNotices", sysNotices);
           return modelAndView(prefix + "/home");
        }
    }


    @ApiOperation(value = "获取登录用户菜单栏", notes = "获取登录用户菜单栏")
    @GetMapping("/getUserMenu")
    @ResponseBody
    public List<SysMenu> getUserMenu() {
        List<SysMenu> sysMenus = sysPermissionService.getSysMenus(ShiroUtils.getUserId());
        return sysMenus;
    }


    /**
     * 请求到登陆界面
     *
     * @param modelMap
     * @return
     */
    @ApiOperation(value = "请求到登陆界面", notes = "请求到登陆界面")
    @GetMapping("/login")
    public String login(ModelMap modelMap) {
        try {
            if ((null != SecurityUtils.getSubject() && SecurityUtils.getSubject().isAuthenticated()) || SecurityUtils.getSubject().isRemembered()) {
                return "redirect:/" + prefix + "/index";
            } else {
                System.out.println("--进行登录验证..验证开始");
                modelMap.put("RollVerification", v2Config.getRollVerification());
                System.out.println("V2Config.getRollVerification()>>>" + v2Config.getRollVerification());
                return "login";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "login";
    }

    /**
     * 用户登陆验证
     * @param user
     * @param captcha
     * @param redirectAttributes
     * @param rememberMe
     * @param request
     * @return
     */
    @ApiOperation(value = "用户登陆验证", notes = "用户登陆验证")
    @PostMapping("/login")
    @ResponseBody
    public AjaxResult login(TSysUser user, String captcha, RedirectAttributes redirectAttributes, boolean rememberMe,
                            HttpServletRequest request) {
        // ModelAndView view =new ModelAndView();
        Boolean yz = false;
        // 获取session中的验证码
        String verCode = (String) request.getSession().getAttribute("captcha");
        // 判断验证码
        if (captcha != null && captcha!=null && verCode != null && captcha.toLowerCase().equals(verCode.trim().toLowerCase())) {
            //清除session中的验证码
            CaptchaUtil.clear(request);
            yz = true;
        }

        // 判断验证码
        if (yz) {
            String userName = user.getUsername();
            Subject currentUser = SecurityUtils.getSubject();
            // 是否验证通过
            if (!currentUser.isAuthenticated()) {
                UsernamePasswordToken token = new UsernamePasswordToken(userName, user.getPassword());
                try {
                    if (rememberMe) {
                        token.setRememberMe(true);
                    }
                    // 存入用户
                    currentUser.login(token);
                    TSysUser user1 = ShiroUtils.getUser();
                    if (user1 != null) {
                        QQUserInfo qqUserInfo = getQQUserInfo();
                        if(qqUserInfo != null && StringUtils.isBlank(user1.getQqOpenid())){
                            TSysUser sysUser = new TSysUser();
                            sysUser.setId(user1.getId());
                            sysUser.setQqOpenid(qqUserInfo.getOpenid());
                            sysUser.setAvatar(qqUserInfo.getFigureurl_qq());
                            sysUser.setSex(qqUserInfo.getGender().equals("男") ? "0" : "1");
                            sysUser.setQqFigureurl(qqUserInfo.getFigureurl());
                            sysUserService.updateTSysUser(sysUser);
                        }
                        request.getSession().setAttribute("user", user1);
                        // 若为前后端分离版本，则可把sessionId返回，作为分离版本的请求头authToken
                        // String authToken = ShiroUtils.getSessionId();
                        // return AjaxResult.successData(200, authToken);
                        return AjaxResult.success();
                    } else {
                        return AjaxResult.error(500, "未知账户");
                    }
                } catch (UnknownAccountException uae) {
                    logger.info("对用户[" + userName + "]进行登录验证..验证未通过,未知账户");
                    return AjaxResult.error(500, "未知账户");
                } catch (IncorrectCredentialsException ice) {
                    logger.info("对用户[" + userName + "]进行登录验证..验证未通过,错误的凭证");
                    return AjaxResult.error(500, "用户名或密码不正确");
                } catch (LockedAccountException lae) {
                    logger.info("对用户[" + userName + "]进行登录验证..验证未通过,账户已锁定");
                    return AjaxResult.error(500, "账户已锁定");
                } catch (ExcessiveAttemptsException eae) {
                    logger.info("对用户[" + userName + "]进行登录验证..验证未通过,错误次数过多");
                    return AjaxResult.error(500, "用户名或密码错误次数过多");
                } catch (AuthenticationException ae) {
                    // 通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
                    logger.info("对用户[" + userName + "]进行登录验证..验证未通过,堆栈轨迹如下");
                    ae.printStackTrace();
                    return AjaxResult.error(500, "用户名或密码不正确");
                }
            } else {
                if (StringUtils.isNotNull(ShiroUtils.getUser())) {
                    // 跳转到 get请求的登陆方法
                    // view.setViewName("redirect:/"+prefix+"/index");
                    return AjaxResult.success();
                } else {
                    return AjaxResult.error(500, "未知账户");
                }
            }
        } else {
            return AjaxResult.error(500, "验证码不正确!");
        }

    }

    /**
     * 手机登录
     * @param user
     * @param rememberMe
     * @param request
     * @return
     */
    @ApiOperation(value = "手机登录", notes = "手机登录")
    @PostMapping("/API/login")
    @ResponseBody
    public AjaxResult APIlogin(TSysUser user, boolean rememberMe, HttpServletRequest request) {
        // ModelAndView view =new ModelAndView();
        Boolean yz = true;
//		if (V2Config.getRollVerification()) {// 滚动验证
//			yz = true;
//		} else {// 图片验证
//			String scode = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
//			yz = StringUtils.isNotEmpty(scode) && StringUtils.isNotEmpty(code) && scode.equals(code);
//		}
        System.out.println("/API/login手机请求");
        // 判断验证码
        if (yz) {
            String userName = user.getUsername();
            Subject currentUser = SecurityUtils.getSubject();
            // 是否验证通过
            if (!currentUser.isAuthenticated()) {
                UsernamePasswordToken token = new UsernamePasswordToken(userName, user.getPassword());
                try {
                    if (rememberMe) {
                        token.setRememberMe(true);
                    }
                    // 存入用户
                    currentUser.login(token);
                    if (StringUtils.isNotNull(ShiroUtils.getUser())) {
                        // 若为前后端分离版本，则可把sessionId返回，作为分离版本的请求头authToken
                        String authToken = ShiroUtils.getSessionId();
                        return AjaxResult.successData(200, authToken);
                        //return AjaxResult.success();
                    } else {
                        return AjaxResult.error(500, "未知账户");
                    }
                } catch (UnknownAccountException uae) {
                    logger.info("对用户[" + userName + "]进行登录验证..验证未通过,未知账户");
                    return AjaxResult.error(500, "未知账户");
                } catch (IncorrectCredentialsException ice) {
                    logger.info("对用户[" + userName + "]进行登录验证..验证未通过,错误的凭证");
                    return AjaxResult.error(500, "用户名或密码不正确");
                } catch (LockedAccountException lae) {
                    logger.info("对用户[" + userName + "]进行登录验证..验证未通过,账户已锁定");
                    return AjaxResult.error(500, "账户已锁定");
                } catch (ExcessiveAttemptsException eae) {
                    logger.info("对用户[" + userName + "]进行登录验证..验证未通过,错误次数过多");
                    return AjaxResult.error(500, "用户名或密码错误次数过多");
                } catch (AuthenticationException ae) {
                    // 通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
                    logger.info("对用户[" + userName + "]进行登录验证..验证未通过,堆栈轨迹如下");
                    ae.printStackTrace();
                    return AjaxResult.error(500, "用户名或密码不正确");
                }
            } else {
                if (StringUtils.isNotNull(ShiroUtils.getUser())) {
                    // 跳转到 get请求的登陆方法
                    // view.setViewName("redirect:/"+prefix+"/index");
                    String authToken = ShiroUtils.getSessionId();
                    return AjaxResult.successData(200, authToken);
                } else {
                    return AjaxResult.error(500, "未知账户");
                }
            }
        } else {
            return AjaxResult.error(500, "验证码不正确!");
        }

    }

    /**
     * 退出登陆
     * @param request
     * @param response
     * @return
     */
    @ApiOperation(value = "退出登陆", notes = "退出登陆")
    @GetMapping("/Loginout")
    @ResponseBody
    public AjaxResult LoginOut(HttpServletRequest request, HttpServletResponse response) {
        // 在这里执行退出系统前需要清空的数据
        Subject subject = SecurityUtils.getSubject();
        // 注销
        subject.logout();
        ServletUtils.getSession().removeAttribute("qqUserInfo");
        return success();
    }

    /**** 页面测试BEGIN ****/

    /**
     * 404页面
     * @param request
     * @param response
     * @return
     */
    @ApiOperation(value = "404页面", notes = "404页面")
    @GetMapping("Out404")
    public String Out404(HttpServletRequest request, HttpServletResponse response) {
        return "redirect:/error/404";
    }

    /**
     * 403页面
     * @param request
     * @param response
     * @return
     */
    @ApiOperation(value = "403页面", notes = "403页面")
    @GetMapping("Out403")
    public String Out403(HttpServletRequest request, HttpServletResponse response) {
        return "redirect:/error/403";
    }

    /**
     * 500页面
     * @param request
     * @param response
     * @return
     */
    @ApiOperation(value = "500页面", notes = "500页面")
    @GetMapping("Out500")
    public String Out500(HttpServletRequest request, HttpServletResponse response) {
        return "redirect:/error/500";
    }

    /**
     * 权限测试跳转页面
     * @param request
     * @param response
     * @return
     */
    @ApiOperation(value = "权限测试跳转页面", notes = "权限测试跳转页面")
    @GetMapping("Outqx")
    @RequiresPermissions("system:user:asd")
    public String Outqx(HttpServletRequest request, HttpServletResponse response) {
        return "redirect:/error/500";
    }
    /**** 页面测试EDN ****/
}
